// 导入类型定义
import { ReportData, ErrorInfo, PerformanceInfo, BehaviorInfo, SDKConfig } from '../types'; // 导入相关类型
import { generateSessionId, deepClone } from '../utils'; // 导入工具函数

// 上报器类，负责缓存和上报所有监控数据
export class Reporter {
  private config: SDKConfig; // SDK 配置
  private sessionId: string; // 会话ID
  private errorCache: ErrorInfo[] = []; // 错误缓存队列
  private performanceCache: PerformanceInfo[] = []; // 性能缓存队列
  private behaviorCache: BehaviorInfo[] = []; // 行为缓存队列
  private reportTimer: number | null = null; // 定时上报定时器ID
  private isDestroyed = false; // 是否已销毁

  // 构造函数，初始化配置和定时器
  constructor(config: SDKConfig) {
    this.config = config; // 保存配置
    this.sessionId = generateSessionId(); // 生成会话ID
    this.startReportTimer(); // 启动定时上报
  }

  // 上报错误信息，加入缓存
  public reportError(error: ErrorInfo): void {
    if (this.isDestroyed) return; // 已销毁则不处理
    this.errorCache.push(deepClone(error)); // 深拷贝后加入缓存
    this.checkCacheSize(); // 检查缓存大小
  }

  // 上报性能信息，加入缓存
  public reportPerformance(performance: PerformanceInfo): void {
    if (this.isDestroyed) return; // 已销毁则不处理
    this.performanceCache.push(deepClone(performance)); // 深拷贝后加入缓存
    this.checkCacheSize(); // 检查缓存大小
  }

  // 上报用户行为，加入缓存
  public reportBehavior(behavior: BehaviorInfo): void {
    if (this.isDestroyed) return; // 已销毁则不处理
    this.behaviorCache.push(deepClone(behavior)); // 深拷贝后加入缓存
    this.checkCacheSize(); // 检查缓存大小
  }

  // 检查缓存队列长度，超出则裁剪
  private checkCacheSize(): void {
    const maxSize = this.config.maxCacheSize || 100; // 最大缓存数
    if (this.errorCache.length > maxSize) {
      this.errorCache = this.errorCache.slice(-maxSize); // 只保留最新的 maxSize 条
    }
    if (this.performanceCache.length > maxSize) {
      this.performanceCache = this.performanceCache.slice(-maxSize); // 只保留最新的 maxSize 条
    }
    if (this.behaviorCache.length > maxSize) {
      this.behaviorCache = this.behaviorCache.slice(-maxSize); // 只保留最新的 maxSize 条
    }
  }

  // 启动定时上报，定期 flush
  private startReportTimer(): void {
    const interval = this.config.reportInterval || 5000; // 上报间隔，默认5秒
    this.reportTimer = window.setInterval(() => {
      this.flush(); // 定时上报所有缓存
    }, interval);
  }

  // 立即上报所有缓存数据
  public flush(): void {
    if (this.isDestroyed) return; // 已销毁则不处理
    const reportData: ReportData = {
      appId: this.config.appId, // 应用ID
      appVersion: this.config.appVersion, // 应用版本
      userId: this.config.userId, // 用户ID
      sessionId: this.sessionId, // 会话ID
      errors: this.errorCache.length > 0 ? [...this.errorCache] : undefined, // 错误数据
      performance: this.performanceCache.length > 0 ? this.performanceCache[this.performanceCache.length - 1] : undefined, // 性能数据
      behaviors: this.behaviorCache.length > 0 ? [...this.behaviorCache] : undefined, // 行为数据
      tags: this.config.tags, // 自定义标签
      timestamp: Date.now() // 当前时间戳
    };
    this.errorCache = []; // 清空错误缓存
    this.performanceCache = []; // 清空性能缓存
    this.behaviorCache = []; // 清空行为缓存
    this.sendData(reportData); // 发送数据到服务器
  }

  // 发送数据到服务器，使用 fetch
  private async sendData(data: ReportData): Promise<void> {
    try {
      const response = await fetch(this.config.reportUrl, { // 发送 POST 请求
        method: 'POST', // 请求方法
        headers: {
          'Content-Type': 'application/json', // JSON 格式
          'X-App-Id': this.config.appId, // 应用ID头
          'X-Session-Id': this.sessionId // 会话ID头
        },
        body: JSON.stringify(data), // 序列化数据
        signal: AbortSignal.timeout(10000) // 10秒超时
      });
      if (!response.ok) { // 非200响应
        console.warn('Error monitor SDK: Failed to send data', {
          status: response.status, // 状态码
          statusText: response.statusText // 状态文本
        });
      }
    } catch (error) {
      console.warn('Error monitor SDK: Network error when sending data', error); // 网络异常
      // 网络异常时，将数据重新放回缓存
      if (data.errors) {
        this.errorCache.unshift(...data.errors); // 错误数据回滚
      }
      if (data.performance) {
        this.performanceCache.unshift(data.performance); // 性能数据回滚
      }
      if (data.behaviors) {
        this.behaviorCache.unshift(...data.behaviors); // 行为数据回滚
      }
    }
  }

  // 使用 Beacon API 发送数据（页面卸载时）
  public sendBeacon(): void {
    if (this.isDestroyed) return; // 已销毁则不处理
    const reportData: ReportData = {
      appId: this.config.appId, // 应用ID
      appVersion: this.config.appVersion, // 应用版本
      userId: this.config.userId, // 用户ID
      sessionId: this.sessionId, // 会话ID
      errors: this.errorCache.length > 0 ? [...this.errorCache] : undefined, // 错误数据
      performance: this.performanceCache.length > 0 ? this.performanceCache[this.performanceCache.length - 1] : undefined, // 性能数据
      behaviors: this.behaviorCache.length > 0 ? [...this.behaviorCache] : undefined, // 行为数据
      tags: this.config.tags, // 自定义标签
      timestamp: Date.now() // 当前时间戳
    };
    this.errorCache = []; // 清空错误缓存
    this.performanceCache = []; // 清空性能缓存
    this.behaviorCache = []; // 清空行为缓存
    // 使用 Beacon API 发送数据
    if ('navigator' in window && 'sendBeacon' in navigator) {
      const success = navigator.sendBeacon(
        this.config.reportUrl, // 上报地址
        JSON.stringify(reportData) // 数据
      );
      if (!success) {
        console.warn('Error monitor SDK: Failed to send beacon data'); // 发送失败警告
      }
    }
  }

  // 获取当前缓存状态
  public getCacheStatus(): {
    errorCount: number; // 错误缓存数
    performanceCount: number; // 性能缓存数
    behaviorCount: number; // 行为缓存数
  } {
    return {
      errorCount: this.errorCache.length, // 错误缓存数
      performanceCount: this.performanceCache.length, // 性能缓存数
      behaviorCount: this.behaviorCache.length // 行为缓存数
    };
  }

  // 销毁上报器，清理定时器并发送剩余数据
  public destroy(): void {
    this.isDestroyed = true; // 标记为已销毁
    if (this.reportTimer) {
      clearInterval(this.reportTimer); // 清除定时器
      this.reportTimer = null; // 置空
    }
    this.sendBeacon(); // 发送剩余数据
  }
} 